﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Algorithm.Check;
using Common;
using JX1000;
using static Algorithm.Check.ExtensionForCRC16;

namespace NewDevice.USB
{
    /// <summary>
    /// 采集类型
    /// </summary>
    public enum JX1000_Type
    {
        /// <summary>
        /// 颜色
        /// </summary>
        Color,

        /// <summary>
        /// 亮度
        /// </summary>
        Light,

        /// <summary>
        /// 频率
        /// </summary>
        Frequency
    }

    /// <summary>
    /// 光纤颜色采集卡
    /// </summary>
    public class JX1000
    {
        private bool init = false;
        private int cardCount;
        private string deviceName;
        private JX1000_API jxapi;
        private int com_index = 1;
        private readonly object locker = new object();

        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="name"></param>
        /// <param name="cardCount"></param>
        public JX1000(string name = "LED颜色亮度采集卡", int cardCount = 5)
        {
            this.cardCount = cardCount;
            this.deviceName = name;
            jxapi = new JX1000_API();
            jxapi.RcvDealHandler += new JX1000_API.RcvDealDelegate(dealDataHandler);
        }

        private void dealDataHandler(EVENT_CODE code, string value)
        {
            Mylog.Debug(deviceName: deviceName, message: value);
            switch (code)
            {
                case EVENT_CODE.PortOpen:
                    break;

                case EVENT_CODE.PortClose:
                    break;

                case EVENT_CODE.PortError:
                    break;

                case EVENT_CODE.TesterConnSuc:
                    if (value.Contains("板卡数"))
                    {
                        int count = int.Parse(value.Substring(value.Length - 2, 1));
                        if (count == cardCount)
                        {
                            init = true;
                        }
                    }
                    break;

                case EVENT_CODE.TesterData:
                    break;

                case EVENT_CODE.TesterDownload:
                    break;

                case EVENT_CODE.TesterDownloadPro:
                    break;

                default:
                    break;
            }
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="port"></param>
        public void Connect(string port)
        {
            jxapi.OpenPort(port);
        }

        /// <summary>
        ///
        /// </summary>
        public void Close()
        {
            jxapi.ClosePort();
        }

        //      0  正常
        //     -1 程序异常
        //     -2 发送失败
        //     -3 等待超时
        //      1 参数错误
        //      2 测试仪没有连接板卡
        //      3 对应位置不存在板卡
        //      4 读数据错误

        private Dictionary<int, string> errMessage = new Dictionary<int, string>()
        {
            { -1,"程序异常"},
            { -2,"发送失败"},
            { -3,"等待超时"},
            {  1,"参数错误"},
            {  2,"测试仪没有连接板卡"},
            {  3,"对应位置不存在板卡"},
            {  4,"读数据错误"},
        };

        /// <summary>
        /// 读取色相
        /// </summary>
        /// <param name="modelIndex">1-5模块</param>
        /// <param name="channel">1-8通道</param>
        /// <param name="type"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public int ReadH(int modelIndex, int channel, JX1000_Type type = JX1000_Type.Color)
        {
            if (!init)
            {
                throw new Exception(deviceName + "初始化异常,板卡数量异常");
            }
            lock (locker)
            {
                int addr = 0;
                switch (type)
                {
                    case JX1000_Type.Color:
                        addr = 10 * (channel - 1) + 103;
                        break;

                    case JX1000_Type.Light:
                        addr = 10 * (channel - 1) + 105;
                        break;

                    case JX1000_Type.Frequency:
                        addr = 10 * (channel - 1) + 108;
                        break;

                    default:
                        break;
                }

                int ret = jxapi.DevRead(com_index, modelIndex, addr, 500, out float data);
                Mylog.Debug(deviceName: deviceName, message: $"model[{modelIndex}] channel[{channel}] addr[{addr}] value[{data}]");

                if (ret == 0)
                {
                    return (int)data;
                }
                throw new Exception(errMessage[ret]);
            }
        }

        /// <summary>
        /// 读取色相,
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public int ReadH(int channel, JX1000_Type type = JX1000_Type.Color)
        {
            int modelIndex = (channel - 1) / 8 + 1;
            int ch = (channel - 1) % 8 + 1;

            int addr = 0;
            switch (type)
            {
                case JX1000_Type.Color:
                    addr = 10 * (ch - 1) + 103;
                    break;

                case JX1000_Type.Light:
                    addr = 10 * (ch - 1) + 105;
                    break;

                case JX1000_Type.Frequency:
                    addr = 10 * (ch - 1) + 108;
                    break;

                default:
                    break;
            }

            lock (locker)
            {
                int ret = jxapi.DevRead(com_index, modelIndex, addr, 500, out float data);
                Mylog.Debug(deviceName: deviceName, message: $"model[{modelIndex}] channel[{ch}] addr[{addr}] value[{data}]");

                if (ret == 0)
                {
                    return (int)data;
                }
                throw new Exception(errMessage[ret]);
            }
        }
    }
}